﻿using System;
using System.Net;
using System.Windows;
using System.IO.IsolatedStorage;
using System.Diagnostics;

namespace DnnDash.SimplePhoneApp.Common
{
    internal class AppSettings
    {
        // setting key names
        const string UsernameSettingKey = "UsernameSetting";
        const string PasswordSettingKey = "PasswordSetting";
        const string DomainAliasSettingKey = "DomainAliasSetting";

        // default settings
        const string UsernameSettingDefault = "";
        const string PasswordSettingDefault = "";
        const string DomainAliasSettingDefault = "";

        IsolatedStorageSettings isolatedStore;

        public delegate void OnPingHandler(object sender, PingEventArgs e);
        public event OnPingHandler OnPing;
        #region properties

        /// <summary>
        /// Property to get and set a Username Setting Key.
        /// </summary>
        public string Username
        {
            get
            {
                return GetValueOrDefault<string>(UsernameSettingKey, UsernameSettingDefault);
            }
            set
            {
                AddOrUpdateValue(UsernameSettingKey, value);
                Save();
            }
        }

        /// <summary>
        /// Property to get and set a Password Setting Key.
        /// </summary>
        public string Password
        {
            get
            {
                return GetValueOrDefault<string>(PasswordSettingKey, PasswordSettingDefault);
            }
            set
            {
                AddOrUpdateValue(PasswordSettingKey, value);
                Save();
            }
        }

        /// <summary>
        /// Property to get and set a Domain Alias Setting Key.
        /// </summary>
        public string DomainAlias
        {
            get
            {
                return GetValueOrDefault<string>(DomainAliasSettingKey, DomainAliasSettingDefault);
            }
            set
            {
                AddOrUpdateValue(DomainAliasSettingKey, value);
                Save();
            }
        }

        /// <summary>
        /// Property indicating if credentials exists, such as a Username, Password and Domain has been entered.
        /// </summary>
        public bool CredentialsExist
        {
            get
            {
                return (Username.Length > 0 && Password.Length > 0 && DomainAlias.Length > 0);
            }
        }

        #endregion

        /// <summary>
        /// Constructor that gets the application settings.
        /// </summary>
        public AppSettings()
        {
            try
            {
                // Get the settings for this application.
                isolatedStore = IsolatedStorageSettings.ApplicationSettings;
            }
            catch (Exception e)
            {
                Debug.WriteLine("Exception while using IsolatedStorageSettings: " + e.ToString());
            }
        }

        /// <summary>
        /// Update a setting value for our application. If the setting does not exist, then add the setting.
        /// </summary>
        /// <param name="Key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool AddOrUpdateValue(string Key, Object value)
        {
            bool valueChanged = false;

            // If the key exists
            if (isolatedStore.Contains(Key))
            {
                // If the value has changed
                if (isolatedStore[Key] != value)
                {
                    // Store the new value
                    isolatedStore[Key] = value;
                    valueChanged = true;
                }
            }
            // Otherwise create the key.
            else
            {
                isolatedStore.Add(Key, value);
                valueChanged = true;
            }

            return valueChanged;
        }

        /// <summary>
        /// Get the current value of the setting, or if it is not found, set the setting to the default setting.
        /// </summary>
        /// <typeparam name="valueType"></typeparam>
        /// <param name="Key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public valueType GetValueOrDefault<valueType>(string Key, valueType defaultValue)
        {
            valueType value;

            // If the key exists, retrieve the value.
            if (isolatedStore.Contains(Key))
            {
                value = (valueType)isolatedStore[Key];
            }
            // Otherwise, use the default value.
            else
            {
                value = defaultValue;
            }

            return value;
        }

        /// <summary>
        /// Save the settings.
        /// </summary>
        public void Save()
        {
            isolatedStore.Save();
        }

        public void PingService()
        {
            ServiceRequest<string> ping = new ServiceRequest<string>(this, CallType.GET, "string", "Ping", true, false);
            ping.CallReturned += new ServiceRequest<string>.CallReturnedHandler(ping_CallReturned);
            ping.CallService();
        }

        void ping_CallReturned(object sender, ServiceResponseEventArgs<string> e)
        {
            if (e.StatusCode == HttpStatusCode.OK)
            {
                //if anonymous call 
                if (e.CallName == "Ping")
                {
                    //then call with settings
                    ServiceRequest<string> pingHost = new ServiceRequest<string>(this, CallType.GET, "string", "PingHost", false, false);
                    pingHost.CallReturned += new ServiceRequest<string>.CallReturnedHandler(ping_CallReturned);
                    pingHost.CallService();
                }
            }
            if (OnPing != null)
            {
                PingEventArgs pea = new PingEventArgs();
                pea.CallName = e.CallName;
                pea.StatusCode = e.StatusCode;
                pea.PingResult = e.ReturnValue;
                OnPing(this, pea);
            }
        }
    }
    public class PingEventArgs : EventArgs
    {
        public string CallName { get; set; }
        public HttpStatusCode StatusCode { get; set; }
        public string PingResult { get; set; }
    }
}
